#include <stdio.h>
#include <stdlib.h>
#include <unistd.h>
#include <string.h>
#include <stdint.h>
#include <syslog.h>
#include <signal.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include <errno.h>
#include <iperf_api.h>

// 全局变量用于信号处理
static struct iperf_test *global_test = NULL;
static int running = 1;

// 信号处理函数
void signal_handler(int signo)
{
    if (signo == SIGTERM || signo == SIGINT)
    {
        syslog(LOG_NOTICE, "Received signal %d, shutting down...", signo);
        running = 0;
        if (global_test)
        {
            iperf_free_test(global_test);
        }
        closelog();
        exit(EXIT_SUCCESS);
    }
}

// 守护进程初始化
void daemonize(const char *cmd)
{
    int i, fd0, fd1, fd2;
    pid_t pid;
    struct sigaction sa;
    umask(0);

    // 第一次fork
    if ((pid = fork()) < 0)
    {
        perror("fork error");
        exit(EXIT_FAILURE);
    }
    else if (pid != 0)
    {
        exit(EXIT_SUCCESS);
    }

    // 创建新会话
    setsid();

    // 设置信号处理
    sa.sa_handler = signal_handler;
    sigemptyset(&sa.sa_mask);
    sa.sa_flags = 0;
    sigaction(SIGTERM, &sa, NULL);
    sigaction(SIGINT, &sa, NULL);

    // 第二次fork
    if ((pid = fork()) < 0)
    {
        perror("fork error");
        exit(EXIT_FAILURE);
    }
    else if (pid != 0)
    {
        exit(EXIT_SUCCESS);
    }

    // 更改工作目录
    chdir("/");

    // 关闭所有打开的文件描述符
    for (i = sysconf(_SC_OPEN_MAX); i >= 0; i--)
    {
        close(i);
    }

    // 重定向标准输入、输出和错误
    fd0 = open("/dev/null", O_RDWR);
    fd1 = dup(fd0);
    fd2 = dup(fd0);

    // 初始化日志系统
    openlog(cmd, LOG_CONS | LOG_PID, LOG_DAEMON);
}

int main(int argc, char **argv)
{
    char *argv0;
    int port = 20080; // 固定端口号为 20080
    int consecutive_errors;

    argv0 = strrchr(argv[0], '/');
    if (argv0 != NULL)
        ++argv0;
    else
        argv0 = argv[0];

    // 初始化为守护进程
    daemonize(argv0);
    syslog(LOG_NOTICE, "iperf3 server daemon started on port %d", port);

    // 创建并配置测试
    global_test = iperf_new_test();
    if (global_test == NULL)
    {
        syslog(LOG_ERR, "failed to create test");
        exit(EXIT_FAILURE);
    }

    iperf_defaults(global_test);
    iperf_set_verbose(global_test, 1);
    iperf_set_test_role(global_test, 's');
    iperf_set_test_server_port(global_test, port);

    consecutive_errors = 0;
    while (running)
    {
        if (iperf_run_server(global_test) < 0)
        {
            syslog(LOG_ERR, "error - %s", iperf_strerror(i_errno));
            ++consecutive_errors;
            if (consecutive_errors >= 5)
            {
                syslog(LOG_ERR, "too many errors, exiting");
                break;
            }
        }
        else
        {
            consecutive_errors = 0;
        }
        iperf_reset_test(global_test);
    }

    iperf_free_test(global_test);
    syslog(LOG_NOTICE, "iperf3 server daemon stopped");
    closelog();
    exit(EXIT_SUCCESS);
}